﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using MapleLib.WzLib;
using MapleLib.WzLib.Util;
using MapleLib.WzLib.WzProperties;

namespace MapleLib.Examples.MapEditor
{
	public partial class MapEditorForm : Form
	{

		public WzFile mapWZ;
		public WzFile npcWZ;
		public WzFile mobWZ;
		public WzFile reactorWZ;
		public WzMap currentMap;
		public bool loadedWZ = false;

		public bool showTile;
		public bool showObj;
		public bool showLife;
		public bool showFH;
		public bool showLR;
		public bool showSeat;
		public bool showPort;
		public bool showReact;

		public MapEditorForm()
		{
			InitializeComponent();
			this.toolStripNumberControl1.NumericUpDown.Minimum = 0;
			this.toolStripNumberControl1.NumericUpDown.Maximum = 7;
			showTile = showTileButton1.Checked;
			showObj = showObjectButton1.Checked;
			showLife = showLifeButton1.Checked;
			showFH = showFHButton1.Checked;
			showLR = showLRButton1.Checked;
			showSeat = showTileButton1.Checked;
			showPort = showPortButton1.Checked;
			showReact = showReactButton1.Checked;
		}

		private void openToolStripButton_Click(object sender, EventArgs e)
		{
			if (!loadedWZ)
			{
				OpenFileDialog dialog = new OpenFileDialog();
				dialog.Filter = "|Map.wz";
				dialog.InitialDirectory = @"C:\Nexon\MapleStory";
				dialog.Title = "Open";
				string filePath = "";
				if (dialog.ShowDialog() == DialogResult.OK)
				{
					filePath = Path.GetDirectoryName(dialog.FileName);
				}
				if (filePath == String.Empty)
				{
					throw new Exception("Uses Didnt Select Valid File");
				}


				mapWZ = new WzFile(filePath + "/Map.wz", WzMapleVersion.GMS);
				npcWZ = new WzFile(filePath + "/Npc.wz", WzMapleVersion.GMS);
				mobWZ = new WzFile(filePath + "/Mob.wz", WzMapleVersion.GMS);
				reactorWZ = new WzFile(filePath + "/Reactor.wz", WzMapleVersion.GMS);
				mapWZ.ParseWzFile();
				npcWZ.ParseWzFile();
				mobWZ.ParseWzFile();
				reactorWZ.ParseWzFile();
				loadedWZ = true;
			}

			List<WzImage> availableMaps = new List<WzImage>();
			foreach (WzDirectory mapDir in mapWZ.WzDirectory.GetDirectoryByName("Map").WzDirectories)
			{
				foreach (WzImage mapImg in mapDir.WzImages)
				{
					availableMaps.Add(mapImg);
				}
			}
			availableMaps.Sort(delegate(WzImage i1, WzImage i2) { return i1.Name.CompareTo(i2.Name); });

			SelectMapForm mapSelect = new SelectMapForm(availableMaps);
			WzImage currentImg = null;
			if (mapSelect.ShowDialog() == DialogResult.OK)
			{
				currentImg = mapSelect.selectedImg;
			}

			if (currentImg == null)
			{
				//throw new Exception("Error: Null Image File");
				return;
			}

			currentMap = new WzMap();
			string idStr = currentImg.Name.Substring(0, 9);
			currentMap.id = int.Parse(idStr);
			currentMap.imgName = idStr + ".img";
			currentMap.img = mapWZ.WzDirectory.GetDirectoryByName("Map").GetDirectoryByName("Map" + (currentMap.id / 100000000)).GetImageByName(idStr + ".img");
			currentMap.mapWZ = mapWZ;
			currentMap.npcWZ = npcWZ;
			currentMap.mobWZ = mobWZ;
			currentMap.reactorWZ = reactorWZ;

			currentMap.load();
			reloadMap();
		}

		public void reloadMap()
		{
			int drawMask = 0;
			if (showTile)
			{
				drawMask |= (int)WzMapDrawMask.TILE;
			}
			if (showObj)
			{
				drawMask |= (int)WzMapDrawMask.OBJ;
			}
			if (showLife)
			{
				drawMask |= (int)WzMapDrawMask.LIFE;
			}
			if (showFH)
			{
				drawMask |= (int)WzMapDrawMask.FH;
			}
			if (showLR)
			{
				drawMask |= (int)WzMapDrawMask.LR;
			}
			if (showSeat)
			{
				drawMask |= (int)WzMapDrawMask.SEAT;
			}
			if (showPort)
			{
				drawMask |= (int)WzMapDrawMask.PORT;
			}
			if (showReact)
			{
				drawMask |= (int)WzMapDrawMask.REACTOR;
			}
			Bitmap image = currentMap.renderMap(drawMask);
			mapRenderPictureBox1.Size = new Size(image.Width, image.Height);
			mapRenderPictureBox1.Image = image;
		}

		private void saveToolStripButton_Click(object sender, EventArgs e)
		{
			if (currentMap != null)
			{
				//currentMap.save();
			}
		}

		private void newToolStripButton_Click(object sender, EventArgs e)
		{
			//New Map Wizard
		}


		[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip)]
		public class ToolStripNumberControl : ToolStripControlHost
		{
			public ToolStripNumberControl()
				: base(new NumericUpDown())
			{

			}

			protected override void OnSubscribeControlEvents(Control control)
			{
				base.OnSubscribeControlEvents(control);
				((NumericUpDown)control).ValueChanged += new EventHandler(OnValueChanged);
			}

			protected override void OnUnsubscribeControlEvents(Control control)
			{
				base.OnUnsubscribeControlEvents(control);
				((NumericUpDown)control).ValueChanged -= new EventHandler(OnValueChanged);
			}

			public event EventHandler ValueChanged;

			public Control NumericUpDownControl
			{
				get { return Control as NumericUpDown; }
			}

			public NumericUpDown NumericUpDown
			{
				get { return Control as NumericUpDown; }
			}

			public void OnValueChanged(object sender, EventArgs e)
			{
				if (ValueChanged != null)
				{
					ValueChanged(this, e);
				}
			}
		}

		private void showTileButton1_Click(object sender, EventArgs e)
		{
			showTile = showTileButton1.Checked;
			reloadMap();
		}

		private void showObjectButton1_Click(object sender, EventArgs e)
		{
			showObj = showObjectButton1.Checked;
			reloadMap();
		}

		private void showLifeButton1_Click(object sender, EventArgs e)
		{
			showLife = showLifeButton1.Checked;
			reloadMap();
		}

		private void showFHButton1_Click(object sender, EventArgs e)
		{
			showFH = showFHButton1.Checked;
			reloadMap();
		}

		private void showLRButton1_Click(object sender, EventArgs e)
		{
			showLR = showLRButton1.Checked;
			reloadMap();
		}

		private void showSeatButton1_Click(object sender, EventArgs e)
		{
			showSeat = showSeatButton1.Checked;
			reloadMap();
		}

		private void showPortButton1_Click(object sender, EventArgs e)
		{
			showPort = showPortButton1.Checked;
			reloadMap();
		}

		private void showReactButton1_Click(object sender, EventArgs e)
		{
			showReact = showReactButton1.Checked;
			reloadMap();
		}

		private void mapRenderPictureBox1_Click(object sender, EventArgs e)
		{
			this.Cursor = null;
			MouseEventArgs ee = (MouseEventArgs)e;
			if (editReactButton1.Checked && (currentMap.drawMask & ((int)WzMapDrawMask.REACTOR)) != 0)
			{
				foreach (WzReactorObject reactor in currentMap.mapReactor)
				{
					if (reactor.drawRect.Contains(new Point(ee.X, ee.Y)))
					{
						MessageBox.Show("REACTOR CLICKED: " + reactor.idStr);
						this.Cursor = new Cursor(reactor.image.GetHicon());
					}
				}
			}
			else if (editLifeButton1.Checked && (currentMap.drawMask & ((int)WzMapDrawMask.LIFE)) != 0)
			{
				foreach (WzLifeObject life in currentMap.mapLife)
				{
					if (life.drawRect.Contains(new Point(ee.X, ee.Y)))
					{
						MessageBox.Show("LIFE CLICKED: " + life.id);
						this.Cursor = new Cursor(life.image.GetHicon());
					}
				}
			}
		}

		private void mapRenderPictureBox1_MouseMove(object sender, MouseEventArgs e)
		{
			mapPositionLabel1.Text = "Map Position: " + e.X + "." + e.Y;
		}
	}
}